let lex=require("./lex");


exports.grammar=function(target_text){
    //固定文法
    let grammars={
        'E'     :   [[['T','E\'']                ],   [   [42,41   ]              ]   ],
        'E\''   :   [[['+','T','E\''],['Epsilon']],   [   [39,42,41]   ,   [34]   ]   ],
        'T\''   :   [[['*','F','T\''],['Epsilon']],   [   [38,42,41]   ,   [34]   ]   ],
        'T'     :   [[['F','T\'']                ],   [   [42,41   ]              ]   ],

        'F'     :   [[['(','E',')'  ],['id'     ]],   [   [36,42,37]   ,   [33]   ]   ]
    };
    let collector=[];
    let stack_lex=[];
    let stack_inn=[];

    let lex_result=lex.lexFirst(target_text[0]);
    let flag1=false,flag2=false,flag4=false;
    let times=0;
    let flag5=false;
    for(let i=0;i<lex_result.length;i+=2){

        if(flag4){
            flag4=false;
            i-=2;
        }else{
            let temp_lex=lex_result[i];
            let temp_inn=lex_result[i+1];

            if(temp_inn==="#") {
                flag5=true;
                // console.log("<到达末尾不再压栈>");
                break;
            }
            times=0;
            stack_lex.push(temp_lex);
            stack_inn.push(temp_inn);
        }



        // console.log("<以方式1压栈  "+stack_lex+"   "+stack_inn+">");

        flag1=false;
        flag2=false;
        flag4=false;

        while(!flag2&&i<=lex_result.length) {
            for (let j in grammars) {                           //遍历文法条目
                if(j==='E' && !flag5) continue;
                for (let k = 0; k < grammars[j][1].length; k++) {  //得到文法可能性的分支数
                    if(grammars[j][1][k]===34) continue;
                    for (let l = stack_lex.length - 1; l >= 0; l--) { //反序遍历栈内元素
                        // console.log("length="+grammars[j][1][k].length+"   grammars[0]:"+grammars[j][0][k]+"    grammars[1]="+grammars[j][1][k]);
                        // console.log("l="+l+"    栈长度:"+stack_lex.length+"   length="+(stack_lex.length-l)+"  inn="+stack_inn+"    lex="+stack_lex);
                        flag1=false;


                        if(stack_lex.length-l!==grammars[j][1][k].length&&(stack_lex.length-l)-grammars[j][1][k].length!==-1){
                            flag1=true;
                        }else{
                            let flag3=true;
                            for (let m = l; m<grammars[j][1][k].length+l; m++) {           //进行匹配
                                // console.log("m="+m);

                                if(stack_lex[m]&&stack_lex[m]===42||stack_lex[m]===41){
                                    // console.log("该字符为非终结符"+stack_lex[m]+"   "+stack_inn[m]+"   "+grammars[j][0][0][m-l]);
                                    flag3=false;
                                    if(stack_inn[m]!==grammars[j][0][0][m-l]){
                                        // console.log("判断非终结字符与语法不匹配 字符"+stack_inn[m]+"   语法需要"+grammars[j][0][0][m-l]);
                                        flag1=true;
                                        flag3=true;
                                        break;
                                    }else{
                                        // console.log("判断非终结字符与语法匹配 字符"+stack_inn[m]+"   语法需要"+grammars[j][0][0][m-l]);
                                    }
                                }else if(stack_lex[m]){
                                    // console.log("该字符为终结符"+stack_lex[m]);
                                }else{
                                    // console.log("未能成功匹配"+stack_lex+"  "+m);
                                }


                                if (!stack_lex[m]||stack_lex[m] !== grammars[j][1][k][m-l]) {
                                    if(!stack_lex[m]&&m>l&&!flag3){
                                        let temp_grammars=grammars[j][0][k][m-l];
                                        let len_grammars =grammars[temp_grammars][1].length-1;
                                        if(grammars[temp_grammars][1][len_grammars][0]===34){
                                            // console.log('该项可为空,进行匹配');
                                            break;
                                        }
                                    }
                                    // console.log("匹配失败");
                                    flag1 = true;
                                    break;
                                }
                            }
                            // console.log("       -------------        ");
                        }



                        if (!flag1) {
                            flag2 = true;
                            // console.log("已匹配 栈内元素"+stack_inn+"和语法条目"+grammars[j][0][k]);
                            collector.push(j);
                            collector.push(grammars[j][0][k]);
                            for (let n = l; n <=stack_lex.length ; n++) {
                                stack_lex.pop();
                                stack_inn.pop()
                            }
                            stack_lex.push(lex.lexOne(j));
                            stack_inn.push(j);
                            // console.log("<以方式2压栈  "+stack_lex+"   "+stack_inn+">");
                            break;
                        }
                    }
                    // console.log("    - - - - - - - - - - - - - - - -");
                    if (flag2) break;
                }
                if (flag2) break;
            }
            // console.log("inside i="+i);
            if(!flag2){

                i+=2;
                temp_lex=lex_result[i];
                temp_inn=lex_result[i+1];
                if(!temp_inn||temp_inn==="#"){
                    // console.log("<到达末尾不再压栈>");
                    flag5=true;
                }else {

                    stack_lex.push(temp_lex);
                    stack_inn.push(temp_inn);
                    // console.log("i:" + i + "   lex:" + lex_result[i] + "    inn:" + temp_inn);
                    // console.log("<以方式3压栈  " + stack_lex + "   " + stack_inn + ">");
                }

            }else{
                flag4=true;
            }
            // console.log("------------------------------------");
        }
    }
    // console.log(collector);
    if(collector.indexOf('E')<0) console.log(aa);
    return collector;
};